import pandas as pd
from pyproj import Transformer, pj_ellps

pd.set_option('display.float_format', lambda x: '%.10f' % x)
pd.set_option('display.max_rows', None)


def create_proj_params(lon_0, a, rf):
    proj_params = {
        "proj": "tmerc",  # 投影（根据选择的投影动态变化）
        "lon_0": lon_0,
        "x_0": 500000,
        "y_0": 0,
        "a": a,  # 长半轴
        "rf": rf,  # 扁率倒数
        "units": "m",
    }
    return proj_params


def create_utm_params(zone, a, rf):
    proj_params = {
        "proj": "utm",  # 投影（根据选择的投影动态变化）
        "zone": zone,
        "a": a,  # 长半轴
        "rf": rf,  # 扁率倒数
        "units": "m",
    }
    return proj_params


# 生成转换器，用于高斯正反算
def gauss_reversals(proj_way, src_choose, src_central_meridian, *args):
    # 定义源数据的投影坐标系和中央子午线
    if proj_way == "高斯克吕格投影":
        match src_choose:
            case "1954北京坐标系":
                a, rf = pj_ellps["krass"]["a"], pj_ellps['krass']['rf']
                src_proj_params = create_proj_params(src_central_meridian, a, rf)
            case "1980西安坐标系":
                a, rf = pj_ellps["IAU76"]["a"], pj_ellps['IAU76']['rf']
                src_proj_params = create_proj_params(src_central_meridian, a, rf)
            case "2000国家大地坐标系":
                a, rf = pj_ellps["GRS80"]["a"], pj_ellps['GRS80']['rf']
                src_proj_params = create_proj_params(src_central_meridian, a, rf)
            case _:
                src_input_a = args[0]  # 长半轴
                src_input_rf = args[1]  # 扁率倒数
                src_proj_params = create_proj_params(src_central_meridian, src_input_a, src_input_rf)
            # 创建转换器
        tf = Transformer.from_proj("EPSG:4490", src_proj_params)
        return tf
    elif proj_way == "UTM":
        match src_choose:
            case "1954北京坐标系":
                a, rf = pj_ellps["krass"]["a"], pj_ellps['krass']['rf']
                src_proj_params = create_utm_params(src_central_meridian, a, rf)
            case "1980西安坐标系":
                a, rf = pj_ellps["IAU76"]["a"], pj_ellps['IAU76']['rf']
                src_proj_params = create_utm_params(src_central_meridian, a, rf)
            case "2000国家大地坐标系":
                a, rf = pj_ellps["GRS80"]["a"], pj_ellps['GRS80']['rf']
                src_proj_params = create_utm_params(src_central_meridian, a, rf)
            case _:
                src_input_a = args[0]  # 长半轴
                src_input_rf = args[1]  # 扁率倒数
                src_proj_params = create_proj_params(src_central_meridian, src_input_a, src_input_rf)
        # 创建转换器
        tf = Transformer.from_proj("EPSG:4490", src_proj_params)
        return tf
    else:
        print("请选择正确的投影方式")


# 高斯反算（投影坐标--经纬度地理坐标）
def gauss_inverse(df, proj_way, src_choose, src_central_meridian, *args):
    # 创建投影转换器
    transformer = gauss_reversals(proj_way, src_choose, src_central_meridian, *args)
    # 使用一个列表，存储转换之后的数据
    processed_data = []
    for index, row in df.iterrows():
        # for循环，处理数据的每一行，对坐标进行高斯正反算
        new_x, new_y, new_z = transformer.transform(row['Y'], row['X'], row['Z'], direction="inverse")
        # 将处理后的数据加入元组中
        processed_data.append({'X': new_y, 'Y': new_x, 'Z': new_z})
    # 元组转为dataframe格式
    new_df = pd.DataFrame(processed_data)
    # 返回数据，供后续使用
    return new_df


# 高斯正算（经纬度地理坐标--投影坐标）
def gauss_forward(df, proj_way, src_choose, src_central_meridian, *args):
    transformer = gauss_reversals(proj_way, src_choose, src_central_meridian, *args)
    processed_data = []
    for index, row in df.iterrows():
        new_x, new_y, new_z = transformer.transform(row['Y'], row['X'], row['Z'])
        processed_data.append({'X': new_y, 'Y': new_x, 'Z': new_z})
    new_df = pd.DataFrame(processed_data)
    return new_df


if __name__ == '__main__':
    df = pd.DataFrame({'X': [116.3372, 116.2372, 116.6232], 'Y': [39.9163, 39.4163, 39.6233], 'Z': [10, 10, 10]})

    gauss_inverse(df, "2000国家大地坐标系", 117)
    gauss_inverse(df, "自定义椭球", 117, 6378137, 298)

    # processed_data = []
    # transformer = gauss_reversals("2000国家大地坐标系", 117)
    # # transformer = gauss_reversals("自定义椭球", 117, 6378137, 298)
    # for index, row in df.iterrows():
    #     new_x, new_y, new_z = transformer.transform(row['Y'], row['X'], row['Z'], direction="inverse")
    #     processed_data.append({'X': new_y, 'Y': new_x, 'Z': new_z})
    # new_df = pd.DataFrame(processed_data)
    # print(new_df)
